package com.fablesoft.projectdatacollect.http;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

import android.os.Environment;

import com.fablesoft.projectdatacollect.MyApplication;
import com.fablesoft.projectdatacollect.bean.BaseResponse;
import com.fablesoft.projectdatacollect.util.Log4jUtil;
import com.fablesoft.projectdatacollect.util.LogUtil;
import com.fablesoft.projectdatacollect.util.StoragePathsManager;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 */
public class JsonUtil
{
    
    private static ObjectMapper objectMapper = new ObjectMapper();
    
    static {
        objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
        objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
        objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
        objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
        objectMapper.setSerializationInclusion(Include.NON_EMPTY);  
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    }
    
    /**
     * 将String类型消息转为对应Action需要的Req对象
     * 
     * @param <T>
     * 
     */
	public static <T extends BaseResponse> T getResponse(String json, Class<T> valueType)
    {
        
        if (json == null)
        {
            return null;
        }
        
        T response = null;
        try
        {
            //getObjectMapper().configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
        	response = objectMapper.readValue(json, valueType);
        	
        }
        catch (Exception e)
        {
			Log4jUtil.e(e.toString());
            e.printStackTrace();
            response = null;
            saveCatchInfo2File(e, json);
        }
        return response;
    }
    
    public static String createReqStr(Map<String, Object> parms)
    {
        StringWriter sw = new StringWriter();
        try
        {
        	objectMapper.writeValue(sw, parms);
        }
        catch (JsonGenerationException e)
        {
			Log4jUtil.e(e.toString());
            e.printStackTrace();
        }
        catch (JsonMappingException e)
        {
			Log4jUtil.e(e.toString());
            e.printStackTrace();
        }
        catch (IOException e)
        {
			Log4jUtil.e(e.toString());
            e.printStackTrace();
        }
        
        return sw.toString();
    }
    
    /**
	 * 保存错误信息到文件中
	 * 
	 * @param ex
	 * @return 返回文件名称,便于将文件传送到服务器
	 */
	private static String saveCatchInfo2File(Throwable ex, String json) {

		StringBuffer sb = new StringBuffer("json:" + json + "\n");
		Writer writer = new StringWriter();
		PrintWriter printWriter = new PrintWriter(writer);
		ex.printStackTrace(printWriter);
		Throwable cause = ex.getCause();
		while (cause != null) {
			cause.printStackTrace(printWriter);
			cause = cause.getCause();
		}
		printWriter.close();
		String result = writer.toString();
		sb.append(result);
		try {
			long timestamp = System.currentTimeMillis();
			DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
			String time = formatter.format(new Date());
			String fileName = "crash-" + time + "-" + timestamp + ".log";
			if (Environment.getExternalStorageState().equals(
					Environment.MEDIA_MOUNTED)) {
				// 当前所有的流量包文件都放在 /mnt/sdcard/TrafficeBonus/下
				// crash文件放在 /mnt/sdcard/TrafficeBonus/TrafficeCrash下
//				String baseDirString = Environment
//						.getExternalStorageDirectory().getPath();
				StoragePathsManager mStoragePathsManager = new StoragePathsManager(MyApplication.getInstance());
				String baseDirString = mStoragePathsManager.getInternalStoragePath();
				File baseDir = new File(baseDirString);
				if (!baseDir.exists()) {
					baseDir.mkdir();
				}

				// String path = "/mnt/sdcard/crash/";
				String path = baseDirString + "/fablesoft/YixintongNT/CrashLog/";
				File dir = new File(path);
				if (!dir.exists()) {
					dir.mkdirs();
				}
				FileOutputStream fos = new FileOutputStream(path + fileName);
				fos.write(sb.toString().getBytes());
				// 发送给开发人员
				sendCrashLog2PM(path + fileName);
				fos.close();
			}
			return fileName;
		} catch (Exception e) {
			Log4jUtil.e(e.toString());
		}
		return null;
	}

	/**
	 * 将捕获的导致崩溃的错误信息发送给开发人员
	 * 
	 * 目前只将log日志保存在sdcard 和输出到LogCat中，并未发送给后台。
	 */
	private static void sendCrashLog2PM(String fileName) {
		FileInputStream fis = null;
		BufferedReader reader = null;
		String s = null;
		try {
			fis = new FileInputStream(fileName);
			reader = new BufferedReader(new InputStreamReader(fis, "GBK"));
			while (true) {
				s = reader.readLine();
				if (s == null)
					break;
			}
		} catch (FileNotFoundException e) {
			Log4jUtil.e(e.toString());
			e.printStackTrace();
		} catch (IOException e) {
			Log4jUtil.e(e.toString());
			e.printStackTrace();
		} finally { // 关闭流
			try {
				if (reader != null)
					reader.close();
				if (fis != null)
					fis.close();
			} catch (IOException e) {
				Log4jUtil.e(e.toString());
				e.printStackTrace();
			}
		}
	}
}
